import helpers from './helpers.js'

export default {
	beginRender: async function (
		landmarks,
		workingCanvas,
		uiImageElements,
		callback
	) {
		return this.processCloudVisionLandmarks(
			landmarks,
			workingCanvas,
			uiImageElements,
			callback
		)
	},

	processCloudVisionLandmarks: function (
		landmarks,
		workingCanvas,
		uiImageElements,
		callback
	) {
		landmarks = this.rotateLandmarks(workingCanvas, landmarks)

		let masks = this.getMaskCoordinatesFromCloudVision(
			landmarks,
			uiImageElements
		)

		let rotatedFaceCanvas = helpers.rotateCanvas(
			workingCanvas,
			landmarks.rollAngle
		)

		let renderedImageMasks = this.renderImageMasks(
			masks,
			workingCanvas,
			rotatedFaceCanvas
		)

		workingCanvas = null
		rotatedFaceCanvas = null

		callback(renderedImageMasks)
	},

	rotateLandmarks: function (workingCanvas, landmarks) {
		landmarks = landmarks[0]

		let rollAngle = landmarks.rollAngle

		for (let i = 0; i < landmarks.landmarks.length; i++) {
			let rotated = helpers.rotateCoordinate(
				workingCanvas.width / 2,
				workingCanvas.height / 2,
				landmarks.landmarks[i].position.x,
				landmarks.landmarks[i].position.y,
				rollAngle
			)

			landmarks.landmarks[i].position.x = rotated[0]
			landmarks.landmarks[i].position.y = rotated[1]
		}

		return landmarks
	},

	getMaskCoordinatesFromCloudVision: function (landmarks, uiImageElements) {
		landmarks = landmarks.landmarks

		let LEFT_EYE_TOP_BOUNDARY = landmarks[16]
		let LEFT_EYE_RIGHT_CORNER = landmarks[17]
		let LEFT_EYE_BOTTOM_BOUNDARY = landmarks[18]
		let LEFT_EYE_LEFT_CORNER = landmarks[19]

		let RIGHT_EYE_TOP_BOUNDARY = landmarks[20]
		let RIGHT_EYE_RIGHT_CORNER = landmarks[21]
		let RIGHT_EYE_BOTTOM_BOUNDARY = landmarks[22]
		let RIGHT_EYE_LEFT_CORNER = landmarks[23]

		let UPPER_LIP = landmarks[8]
		let LOWER_LIP = landmarks[9]
		let MOUTH_LEFT = landmarks[10]
		let MOUTH_RIGHT = landmarks[11]

		let LEFT_EYE_WIDTH =
			LEFT_EYE_RIGHT_CORNER.position.x - LEFT_EYE_LEFT_CORNER.position.x
		let LEFT_EYE_HEIGHT =
			LEFT_EYE_BOTTOM_BOUNDARY.position.y - LEFT_EYE_TOP_BOUNDARY.position.y

		let RIGHT_EYE_WIDTH =
			RIGHT_EYE_RIGHT_CORNER.position.x - RIGHT_EYE_LEFT_CORNER.position.x
		let RIGHT_EYE_HEIGHT =
			RIGHT_EYE_BOTTOM_BOUNDARY.position.y - RIGHT_EYE_TOP_BOUNDARY.position.y

		let MOUTH_HEIGHT = LOWER_LIP.position.y - UPPER_LIP.position.y
		let MOUTH_WIDTH = MOUTH_RIGHT.position.x - MOUTH_LEFT.position.x

		let LEFT_EYE_CENTER = landmarks[0]
		let RIGHT_EYE_CENTER = landmarks[1]
		let MOUTH_CENTER = landmarks[12]

		return [
			{
				maskImage: uiImageElements.EYE_MASK,
				center: LEFT_EYE_CENTER,
				width: LEFT_EYE_WIDTH,
				height: LEFT_EYE_HEIGHT,
				id: 'eyeLeft',
			},
			{
				maskImage: uiImageElements.EYE_MASK,
				center: RIGHT_EYE_CENTER,
				width: RIGHT_EYE_WIDTH,
				height: RIGHT_EYE_HEIGHT,
				id: 'eyeRight',
			},
			{
				maskImage: uiImageElements.MOUTH_MASK,
				center: MOUTH_CENTER,
				width: MOUTH_WIDTH,
				height: MOUTH_HEIGHT,
				id: 'mouth',
			},
		]
	},

	renderImageMasks: function (masks, workingCanvas, rotatedFaceCanvas) {
		let ctx = workingCanvas.getContext('2d')
		let maskOutputs = []

		for (let i in masks) {
			let multiplier
			if (masks[i].id == 'mouth') {
				multiplier = 2.5
			} else {
				multiplier = 3.5
			}

			let maskWidth = Math.round(masks[i].width * multiplier)
			let maskHeight = Math.round(masks[i].width * multiplier)

			ctx.clearRect(0, 0, workingCanvas.width, workingCanvas.height)

			ctx.drawImage(
				masks[i].maskImage,
				Math.round(masks[i].center.position.x - maskWidth / 2),
				Math.round(masks[i].center.position.y - maskWidth / 2),
				maskWidth,
				maskHeight
			)

			ctx.globalCompositeOperation = 'source-in'

			ctx.drawImage(rotatedFaceCanvas, 0, 0)

			let maskOutput = document.createElement('canvas')
			maskOutput.width = maskWidth
			maskOutput.height = maskHeight
			let maskCtx = maskOutput.getContext('2d')

			maskCtx.drawImage(
				workingCanvas,
				Math.round(masks[i].center.position.x - maskWidth / 2),
				Math.round(masks[i].center.position.y - maskWidth / 2),
				maskWidth,
				maskHeight,
				0,
				0,
				maskWidth,
				maskHeight
			)

			maskOutputs.push({
				id: masks[i].id,
				width: maskWidth,
				height: maskHeight,
				maskOutput: maskOutput,
			})

			ctx.globalCompositeOperation = 'destination-atop'
		}

		return maskOutputs
	},
}
